package com.miao.util.img;


import com.drew.imaging.jpeg.JpegMetadataReader;
import com.drew.imaging.jpeg.JpegProcessingException;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;
import com.miao.util.json.JsonUtils;
import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.io.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Created by miao on 2015/4/22.
 */
public class ImageUtils {
    static final String DS90 = "Right side, top (Rotate 90 CW)";
    static final String DS180 = "Bottom, right side (Rotate 180)";
    static final String DS270 = "Left side, bottom (Rotate 270 CW)";

    @Deprecated
    public static BufferedImage readToImage(InputStream in) {
        BufferedImage image = null;
        try {
            image = ImageIO.read(in);
        } catch (ImageFormatException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return image;
    }

    public static BufferedImage readToImageV2(InputStream in) {
        BufferedImage image = null;
        try {
            image = Thumbnails.of(new InputStream[]{in}).scale(1.0D).asBufferedImage();
        } catch (ImageFormatException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return image;
    }

    public static BufferedImage readToImage(byte[] in) {
        InputStream is = new ByteArrayInputStream(in);
        BufferedImage image = readToImageV2(is);
        return image;
    }

    public static BufferedImage readToImage(File file) {
        BufferedImage image = null;
        try {
            Thumbnails.Builder xx = Thumbnails.of(new File[]{file});
            image = xx.size(400, 400).asBufferedImage();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return image;
    }

    public static BufferedImage autoFixS(BufferedImage image, String ori) {
        if (StringUtils.equals(ori, "Right side, top (Rotate 90 CW)")) {
            System.out.println("rotate90SX");
            image = rotate90SX(image);
        } else if (StringUtils.equals(ori, "Bottom, right side (Rotate 180)")) {
            System.out.println("rotate180SX");
            image = rotate180SX(image);
        } else if (StringUtils.equals(ori, "Left side, bottom (Rotate 270 CW)")) {
            System.out.println("rotate270SX");
            image = rotate270SX(image);
        }
        return image;
    }

    public static BufferedImage rotate90SX(BufferedImage bi) {
        int width = bi.getWidth();
        int height = bi.getHeight();
        BufferedImage biFlip = new BufferedImage(height, width, bi.getType());
        for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {
                biFlip.setRGB(height - 1 - j, i, bi.getRGB(i, j));
            }
        }
        return biFlip;
    }

    public static BufferedImage rotate180SX(BufferedImage bi) {
        int width = bi.getWidth();
        int height = bi.getHeight();
        BufferedImage biFlip = new BufferedImage(width, height, bi.getType());
        for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {
                biFlip.setRGB(width - 1 - i, height - 1 - j, bi.getRGB(i, j));
            }
        }
        return biFlip;
    }

    public static BufferedImage rotate270SX(BufferedImage bi) {
        int width = bi.getWidth();
        int height = bi.getHeight();
        BufferedImage biFlip = new BufferedImage(height, width, bi.getType());
        for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {
                biFlip.setRGB(j, width - 1 - i, bi.getRGB(i, j));
            }
        }
        return biFlip;
    }

    public static byte[] writeToFile(BufferedImage image) {
        byte[] data = null;
        ByteOutputStream bos = new ByteOutputStream();
        try {
            ImageIO.write(image, "jpg", bos);
            data = bos.getBytes();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return data;
    }

    public static byte[] writeToFile(BufferedImage image, float quality) {
        byte[] data = null;
        ByteOutputStream bos = new ByteOutputStream();
        try {
            ImageIO.write(image, "jpg", bos);
            data = bos.getBytes();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return data;
    }

    public static byte[] quality(BufferedImage image, float quality) {
        byte[] data = null;
        try {
            float softenFactor = 0.05F;
            float[] softenArray = {0.0F, softenFactor, 0.0F, softenFactor, 1.0F - softenFactor * 4.0F, softenFactor, 0.0F, softenFactor, 0.0F};

            Kernel kernel = new Kernel(3, 3, softenArray);
            ConvolveOp cOp = new ConvolveOp(kernel, 1, null);
            BufferedImage dest = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
            image = cOp.filter(image, dest);

            JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(image);
            ByteOutputStream bos = new ByteOutputStream();
            JPEGImageEncoder enc = JPEGCodec.createJPEGEncoder(bos, jep);
            jep.setQuality(quality, true);
            enc.setJPEGEncodeParam(jep);
            enc.encode(image);
            data = bos.getBytes();
        } catch (ImageFormatException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return data;
    }

    public static Map readInfo(byte[] bytes) {
        Map map = new HashMap();
        try {
            Metadata metadata = null;
            metadata = JpegMetadataReader.readMetadata(new ByteArrayInputStream(bytes));
            Iterator iter = metadata.getDirectories().iterator();
            while (iter.hasNext()) {
                Directory dir = (Directory) iter.next();
                for (Tag t : dir.getTags()) {
                    if (t.getTagName().equals("Orientation")) {
                        System.out.println("=======" + JsonUtils.toJson(t));
                    }
                    map.put(t.getTagName(), t.getDescription());
                }
            }
        } catch (JpegProcessingException e) {
            e =
                    e;

            e.printStackTrace();
        } finally {
        }
        return map;
    }

    public static Map readInfo(InputStream inputStream) {
        Map map = new HashMap();
        try {
            Metadata metadata = null;
            metadata = JpegMetadataReader.readMetadata(inputStream);
            Iterator iter = metadata.getDirectories().iterator();
            while (iter.hasNext()) {
                Directory dir = (Directory) iter.next();
                for (Tag t : dir.getTags())
                    map.put(t.getTagName(), t.getDescription());
            }
        } catch (JpegProcessingException e) {
            e =
                    e;

            e.printStackTrace();
        } finally {
        }
        return map;
    }

    public static void main(String[] args) throws IOException {
//        File[] files = new File("d:/itest/").listFiles();
//        BufferedImage bufferedImage;
//        for (File f : files) {
//            byte[] data = FileUtils.readFileToByteArray(f);
//            bufferedImage = readToImage(data);
//        }
//        System.exit(0);

        build();
    }

    public static Font getFont(String path) {
        File file = new File(path);
        Font font = null;
        if (!file.exists())
            return font;
        try {
            FileInputStream fi = new FileInputStream(file);
            BufferedInputStream fb = new BufferedInputStream(fi);
            Font.createFont(0, fb);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return font;
    }

    public static void build() throws IOException {
        String text = "简介浙江永太科技股份有限公司始建于20世纪末，是专业研发、生产含氟精细化学品的国家火炬重点高新技术企业。公司总部位于中国东南部化学原料药基地";
        int imageWidth = 500;

        int imageHeight = 400;
        BufferedImage image = new BufferedImage(imageWidth, imageHeight, 1);

        Graphics2D g2d = image.createGraphics();
        g2d.setColor(Color.white);
        g2d.fillRect(0, 0, imageWidth, imageHeight);
        g2d.setColor(Color.black);
        g2d.setStroke(new BasicStroke(1.0F));
        g2d.setFont(new Font("宋体", 1, 20));
        g2d.drawString("姓名 : " + text, 50, 75);
        g2d.dispose();

        byte[] data = writeToFile(image);

        FileUtils.writeByteArrayToFile(new File("d:/s.jpg"), data);
    }
}
